package com.microframework.base.data.config;

import java.io.IOException;

import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.microframework.base.core.exception.ConfigParseException;
import com.microframework.base.data.config.base.WebSocketConnectionConfig;
import com.microframework.boot.collect.model.domain.DataSourceConfig;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class ConfigParser {
    
    private final ObjectMapper objectMapper;
    
    public HttpConnectionConfig parseHttpConfig(DataSourceConfig config) {
        try {
            HttpConnectionConfig httpConfig = objectMapper.readValue(
                config.getConnectionConfig(), 
                HttpConnectionConfig.class
            );
            
            // 设置默认值
            if (httpConfig.getMethod() == null) {
                httpConfig.setMethod(HttpConnectionConfig.HttpMethod.GET);
            }
            
            return httpConfig;
        } catch (IOException e) {
            throw new ConfigParseException("Failed to parse HTTP connection config", e);
        }
    }
    
    public MqttConnectionConfig parseMqttConfig(DataSourceConfig config) {
        try {
            MqttConnectionConfig mqttConfig = objectMapper.readValue(
                config.getConnectionConfig(), 
                MqttConnectionConfig.class
            );
            
            // 设置默认值
            if (mqttConfig.getClientId() == null) {
                mqttConfig.setClientId("mqtt-client-" + System.currentTimeMillis());
            }
            
            return mqttConfig;
        } catch (IOException e) {
            throw new ConfigParseException("Failed to parse MQTT connection config", e);
        }
    }
    
    public DatabaseConnectionConfig parseDatabaseConfig(DataSourceConfig config) {
        try {
            DatabaseConnectionConfig dbConfig = objectMapper.readValue(
                config.getConnectionConfig(), 
                DatabaseConnectionConfig.class
            );
            
            // 自动推断驱动类名
            if (dbConfig.getDriverClassName() == null && dbConfig.getDbType() != null) {
                dbConfig.setDriverClassName(inferDriverClassName(dbConfig.getDbType()));
            }
            
            return dbConfig;
        } catch (IOException e) {
            throw new ConfigParseException("Failed to parse Database connection config", e);
        }
    }
    
    public WebSocketConnectionConfig parseWebSocketConfig(DataSourceConfig config) {
        try {
            return objectMapper.readValue(
                config.getConnectionConfig(), 
                WebSocketConnectionConfig.class
            );
        } catch (IOException e) {
            throw new ConfigParseException("Failed to parse WebSocket connection config", e);
        }
    }
    
    public ExcelConnectionConfig parseExcelConfig(DataSourceConfig config) {
        try {
            ExcelConnectionConfig excelConfig = objectMapper.readValue(
                config.getConnectionConfig(), 
                ExcelConnectionConfig.class
            );
            
            // 推断文件类型
            if (excelConfig.getFileType() == null && excelConfig.getFilePath() != null) {
                excelConfig.setFileType(inferExcelType(excelConfig.getFilePath()));
            }
            
            return excelConfig;
        } catch (IOException e) {
            throw new ConfigParseException("Failed to parse Excel connection config", e);
        }
    }
    
    private String inferDriverClassName(DatabaseConnectionConfig.DbType dbType) {
        switch (dbType) {
            case MYSQL: return "com.mysql.cj.jdbc.Driver";
            case POSTGRESQL: return "org.postgresql.Driver";
            case ORACLE: return "oracle.jdbc.OracleDriver";
            case SQLSERVER: return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
            case H2: return "org.h2.Driver";
            default: throw new IllegalArgumentException("Unsupported database type");
        }
    }
    
    private ExcelConnectionConfig.ExcelType inferExcelType(String filePath) {
        if (filePath.toLowerCase().endsWith(".xlsx")) {
            return ExcelConnectionConfig.ExcelType.XLSX;
        } else if (filePath.toLowerCase().endsWith(".xls")) {
            return ExcelConnectionConfig.ExcelType.XLS;
        }
        throw new IllegalArgumentException("Unsupported Excel file extension");
    }
}